package com.lctandil.geophotos;

import java.util.ArrayList;
import java.util.List;


import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.google.ads.AdRequest;
import com.google.ads.AdSize;
import com.google.ads.AdView;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.Overlay;
import com.lctandil.geophotos.ballon.CustomItemizedOverlay;
import com.lctandil.geophotos.ballon.CustomOverlayItem;
import com.lctandil.geophotos.clustering.Cluster;
import com.lctandil.geophotos.clustering.ImageInfo;
import com.lctandil.geophotos.data.Cache;
import com.lctandil.geophotos.data.ImageLoader;
import com.readystatesoftware.maps.MapViewListener;
import com.readystatesoftware.maps.OnSingleTapListener;
import com.readystatesoftware.maps.TapControlledMapView;

public class MainActivity extends MapActivity {

	private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
	private MapController mapController;
	private TapControlledMapView mapView;
	private CustomItemizedOverlay<CustomOverlayItem> itemizedOverlay;
	private int zoomLevel = 2;
	private ImageView camera;
	private float distance;
	private AdView adView;  

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.layout.menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getItemId() == R.id.ratethisapp) {
			Intent intent = new Intent(Intent.ACTION_VIEW);
			intent.setData(Uri.parse("market://details?id=com.lctandil.geophotos"));
			startActivity(intent);
			return true;
		}
		return true;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
//		TapControlledMapView layout = (TapControlledMapView)findViewById(R.id.mapview);
//		RelativeLayout layout = (RelativeLayout)findViewById(R.id.LinearLayout1);
		LinearLayout layout = (LinearLayout)findViewById(R.id.LinearLayout1);

		adView = new AdView(this, AdSize.BANNER, "98c4086954cb4e6b");
		layout.addView(adView, 0);
		        
		// Initiate a generic request to load it with an ad	    
	    AdRequest request = new AdRequest();
	    adView.loadAd(request);
	    
		camera = (ImageView)findViewById(R.id.camera_icon);
		
		mapView = (TapControlledMapView) findViewById(R.id.mapview);
		mapView.setBuiltInZoomControls(true);
		mapView.setOnSingleTapListener(new OnSingleTapListener() {
			public boolean onSingleTap(MotionEvent e) {
				itemizedOverlay.hideAllBalloons();
				return true;
			}
		});

		List<Overlay> mapOverlays = mapView.getOverlays();
		Drawable drawable = this.getResources().getDrawable(
				R.drawable.pin);
		itemizedOverlay = new CustomItemizedOverlay<CustomOverlayItem>(
				drawable, mapView);

		itemizedOverlay.setShowClose(false);
		itemizedOverlay.setShowDisclosure(true);

		mapOverlays.add(itemizedOverlay);

		mapController = mapView.getController();
		mapController.setZoom(zoomLevel);

		mapView.setMapViewListener(new MapViewListener() {			
			public void onZoom(GeoPoint oldTopLeft, GeoPoint oldCenter,
					GeoPoint oldBottomRight, GeoPoint newTopLeft,
					GeoPoint newCenter, GeoPoint newBottomRight,
					int oldZoomLevel, int newZoomLevel) {
						zoomLevel = newZoomLevel;
						distance = Measurement.getDistanceInMiles(newTopLeft,
								newBottomRight);
						recalculateClusters(distance);
			}
			public void onPan(GeoPoint oldTopLeft, GeoPoint oldCenter,
					GeoPoint oldBottomRight, GeoPoint newTopLeft,
					GeoPoint newCenter, GeoPoint newBottomRight) {
				// TODO Auto-generated method stub
			}
		});
		camera.setOnClickListener(new OnClickListener() {			
			public void onClick(View v) {
				Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
				startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
			}
		});
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
	        if (resultCode == RESULT_OK) {
	            // Image captured
	            ImageLoader.loadCameraImages(this);
				recalculateClusters(distance);
	        } else if (resultCode == RESULT_CANCELED) {
	        	// User canceled camera request
	        } else {
	            // Image capture failed, advise user
	        }
	    }
	}
	
	@Override
	protected void onDestroy(){
		adView.destroy();
		super.onDestroy();
	}
	

	@SuppressLint("ParserError")
	private void addMarker(GeoPoint point, String title, String message,
			String url, Cluster cluster) {
		CustomOverlayItem overlayItem = new CustomOverlayItem(point, title,
				message, url, cluster);
		this.itemizedOverlay.addOverlay(overlayItem);
	}
	
	private void showNoTagErrorPopup (){
		Dialog dialog = new Dialog(this);
		dialog.setContentView(R.layout.custom_dialog);
		dialog.setTitle("No pictures with geo-tag found");
		TextView text = (TextView) dialog.findViewById(R.id.text);
		text.setText(Constants.TEXT_NO_GEOTAG);
		ImageView image = (ImageView) dialog.findViewById(R.id.image);
		image.setImageResource(R.drawable.geophotos_icon);
		dialog.show();
	}

	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}

	private LoadMarkerTask loadMarkerTask;
	
	public void recalculateClusters(float distance) {
		this.itemizedOverlay.hideAllBalloons();
		if (loadMarkerTask!=null)
			loadMarkerTask.cancel(true);
		loadMarkerTask=new LoadMarkerTask();
		loadMarkerTask.execute(distance);
	}

	public class LoadMarkerTask extends
			AsyncTask<Float, Void, ArrayList<Cluster>> {

		@Override
		protected ArrayList<Cluster> doInBackground(Float... params) {
			ArrayList<Cluster> clusters = new ArrayList<Cluster>();
			float distance = params[0] / 20;
			List<ImageInfo> points = Cache.getInstance().getPoints();
			if (points.size() > 0) {
				Cluster cluster = new Cluster();
				cluster.addImage(points.get(0));
				clusters.add(cluster);
				for (int i = 1; i < points.size(); i++) {
					ImageInfo imageInfo = points.get(i);
					boolean added = false;
					for (int j = 0; j < clusters.size(); j++) {
						cluster = clusters.get(j);
						float pDist = Measurement.getDistanceInMiles(
								cluster.getCenter(), imageInfo.getPoint());
						if (pDist < distance) {
							cluster.addImage(imageInfo);
							added = true;
							break;
						}
					}
					if (!added) {
						cluster = new Cluster();
						cluster.addImage(imageInfo);
						clusters.add(cluster);
					}
				}
			}
			return clusters;
		}

		@Override
		protected void onPostExecute(ArrayList<Cluster> result) {
			MainActivity.this.itemizedOverlay.clear();
			if (result.size() == 0){
				showNoTagErrorPopup();
			}else{
				for (int i = 0; i < result.size(); i++) {
					Cluster cluster = result.get(i);
					ImageInfo img = cluster.getFirst();
					MainActivity.this.addMarker(cluster.getCenter(), cluster.getCount() + " Picture(s)",
							img.getPath(), img.getPath(), cluster);
				}
			}	
			MainActivity.this.mapView.invalidate();
		}
	}

}
